package vh.sphynx;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.Resource.Diagnostic;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.xtext.diagnostics.AbstractDiagnostic;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.resource.XtextSyntaxDiagnostic;

import vh.sphynx.runtime.ExecutionContext;
import vh.sphynx.runtime.SphynxInterpreter;
import vh.sphynx.runtime.VariableStorage;
import vh.sphynx.runtime.impl.DefaultExecutionContext;
import vh.sphynx.scoping.SphynxImportUriResolver;
import vh.sphynx.sphynx.Program;
import vh.sphynx.sphynx.SphynxPackage;
import vh.sphynx.util.ExceptionUtil;

public class Parse {
	
	public static Program loadProgram(String input, ResourceSet rs) {
		Program prog = null;
		
		if (rs == null) rs = new ResourceSetImpl();
		Resource resource = rs.getResource(URI.createFileURI(input), true);
		EList<Diagnostic> errors = resource.getErrors();
		
		if (errors.size() > 0) {
			for(Diagnostic err: errors)  {
				if (err instanceof AbstractDiagnostic) {
					AbstractDiagnostic e = (AbstractDiagnostic) err;
					//INode node = ((AbstractDiagnostic) err).getNode();
					//URI uriToProblem = e.getUriToProblem();
					System.out.printf("Syntax Error [line:%d]: %s\n", e.getLine(), err.getMessage());
				}
			}
		}
		else {
			EObject eobj = resource.getContents().get(0);
			prog = (Program) eobj;
		}
		return prog;
	}

	
	/**
	 * @param args
	 * @throws IOException 
	 */
	@SuppressWarnings("unused")
	public static void main(String[] args) throws IOException {
		SphynxPackage einstance = SphynxPackage.eINSTANCE; // register EistarPackage
		new SphynxStandaloneSetup().createInjectorAndDoEMFRegistration();

		boolean enterToQuit = false;
		
		int fileIdx = 0;
		String input = null;
		
		
		for(fileIdx = 0; fileIdx < args.length && input == null; fileIdx++) 
			switch (args[fileIdx].charAt(0)) {
			case '/':
			case '-':
				if (args[fileIdx].startsWith("s", 1) || args[fileIdx].startsWith("-stop", 1))
					enterToQuit = true;
				else if (args[fileIdx].startsWith("v", 1)) {
					fileIdx++;
					ExceptionUtil.VerboseLevel = Integer.parseInt(args[fileIdx]);
				}
				else if (args[fileIdx].startsWith("i", 1)) {
					fileIdx++;
					SphynxImportUriResolver.addPaths(args[fileIdx]);
				}
				break;
			default:
				input = args[fileIdx];
				break;
			}
		
		if (input == null)
			input = "chrome/test.vhs";
		
		File fi = new File(input).getAbsoluteFile();
		if (!fi.exists()) {
			if (!input.toLowerCase().endsWith(".vhs"))
				fi = new File(input + ".vhs");
			if (!fi.exists()) {
				System.out.println("Input file not found.");
				System.exit(1);
			}
		}
		
		// change directory to the input
		File ip = fi; //new File(input).getAbsoluteFile();
		//File dir = ip.getAbsoluteFile().getParentFile();
		//System.setProperty("user.dir", dir.getAbsolutePath());
		
		//System.out.printf("Compling %s...\n", ip.getAbsolutePath());
		
		ResourceSetImpl rs = new ResourceSetImpl();
		rs.setResourceFactoryRegistry(Resource.Factory.Registry.INSTANCE);
		Program prg = loadProgram(ip.getAbsolutePath(), rs);
		
		if (prg != null) {
			Properties prop = new Properties();
			if (new File("config.cfg").exists()) {
				prop.load(new FileReader("config.cfg"));
			}
		
			SphynxImportUriResolver.addPaths(prop.getProperty("VHS_PATH", "include/"));
			SphynxImportUriResolver.addPaths(System.getenv("VHS_PATH"));
			
			ExecutionContext context = new DefaultExecutionContext(null, null);
			
			Map<String, Object> arguments = new HashMap<String, Object>();
			
			List<String> arg = new ArrayList<String>();
			
			for (int i = fileIdx; i < args.length; i++) {
				if (args[i].startsWith("-")) {
					String key = args[i].substring(1);
					String[] param = key.split(":", 2);
					if (param.length > 1)
						arguments.put(param[0], param[1]);
					else
						arguments.put(param[0], true);
				}
				else arg.add(args[i]);
			}
						
			//System.out.println("Loading program...");		
			SphynxInterpreter interpreter = new SphynxInterpreter();
			context.allocateVariable(VariableStorage.READONLY, true, "ARGS", arg);
			interpreter.execute(prg, context, arguments);			
		}
		if (enterToQuit) {
			System.out.println("[Enter] to exit.");
			System.in.read();
		}
	}

}
